package edu.pku.sei.transformation.codegen;

import java.util.HashMap;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;

import edu.pku.sei.transformation.editor.actions.CodegenAction;
import edu.pku.sei.transformation.editor.model.Transformation;
import edu.pku.sei.transformation.editor.model.execution.TransformationExecution;
import edu.pku.sei.transformation.editor.model.implement.ICodegenElement;

public class CodegenRegister {
	public static CodegenRegister INSTANCE = new CodegenRegister();
	private HashMap<String, CodegenAdapter> actionAdapters = new HashMap<String, CodegenAdapter>();
	
	private CodegenRegister() {
		
	}
	
	public void registCodegenFactory(CodegenAdapter actionClass) {
		actionAdapters.put(actionClass.getLanguage(), actionClass);
	}
	
	public IMenuManager getMenu(Object selectedElement) {
		IMenuManager genaction = new MenuManager("generate code");
		if (selectedElement instanceof Transformation) {
			Transformation trans = (Transformation) selectedElement;
			for (CodegenAdapter adapter : actionAdapters.values()) {
				Action action = new CodegenAction(trans, adapter);
				genaction.add(action);
			}
		} else if (selectedElement instanceof TransformationExecution) {
			TransformationExecution transExe = (TransformationExecution) selectedElement;
			for (CodegenAdapter adapter : actionAdapters.values()) {
				Action action = new CodegenAction(transExe, adapter);
				genaction.add(action);
			}
		}
		return genaction;
	}
	
	public boolean generateCodeIfNotExist(String language, ICodegenElement element) {
		return generateCode(language, element, false);
	}
	
	public boolean generateCode(String language, ICodegenElement element, boolean force) {
		CodegenAdapter adapter = actionAdapters.get(language);
		if (adapter == null) {
			return false;
		} else if (adapter.canGenerate(element) == false) {
			return false;
		} else {
			return adapter.generateCode(element, force);
		}
	}
}
